/* 
 * File:   hardware.h
 * Author: hongkang.tao
 *
 * Created on June 10, 2021, 3:46 PM
 */
/***********************************/
//关于底层硬件的操作在此处进行封装，移植时主要是处理这个文件
/***********************************/
#ifndef _HARDWARE_H_
#define	_HARDWARE_H_

#define F_CPU 20000000UL			//20MHz

#include <util/delay.h>				//使用该头文件需要定义F_CPU宏，值为实际的CPU frequency
#include "wdt.h"
#include <math.h>
#include "../mcc_generated_files/system/system.h"


/******************/
//软件版本号
#define _SOFEWARE_VERSION			"PS-A2907E-V1.0Beta9-SJ-tao"
#define	_SOFTWARE_VERSION_SHROT		"PS-V1.0Beta9"

/******************/

#define UART_0 		0

#define UART_HOST  UART_0


#define FLASH_S_ADDR  		0x1400		//EEPROM,3217有256字节
#define FLASH_SIZE    		256

typedef signed char        	INT8;
typedef signed char        	int8_t;
typedef signed int        	INT16;
typedef signed int        	int16_t;


/****************************************************/
//系统功能剪裁宏
#define CHECK_BAT_3_CELL_EN		0					//检测三节铅酸电池，默认是检测两节
#define CHECK_BAT_LIION_EN		0					//检测锂电池包功能
#define CHECK_BAT_RES_EN		1					//检测电池内阻功能
#define CHECK_CHARGER_DAC_EN	1					//充电器DAC控制功能
#define CHECK_HOST_485_EN       1					//主机485通讯功能，需要软件控制收发方向


/****************************************************/
//硬件底层功能函数封装，与硬件高度相关
#define CHARGER_ON()		ON_CHARGER_SetHigh()		//开充电开关
#define CHARGER_OFF()		ON_CHARGER_SetLow()			//关充电开关
#define CHARGER_IO_STATE()	(ON_CHARGER_GetValue()>>5)	//获取充电开关状态
#define MAINOFF_ON()		MAINOFF_SetLow()			//开主电开关
#define MAINOFF_OFF()		MAINOFF_SetHigh()			//关主电开关
#define MAINOFF_IO_STATE()	(MAINOFF_GetValue()>>7)		//获取主电开关状态
#define BATOFF_ON()			BATOFF_SetHigh()			//开备电开关
#define BATOFF_OFF()		BATOFF_SetLow()				//关备电开关
#define BATOFF_IO_STATE()	(BATOFF_GetValue()>>0)		//获取备电开关状态
//#define SWITCH_LIION_ON()						//充电器切换为锂电模式
//#define SWITCH_LIION_OFF()					//充电器切换为铅酸模式
//#define SWITCHLIION_IO_STATE()				//获取切换开关状态
#define TIGER_IO_STATE()	(TIGER_GetValue()>>5)		//读取按键状态
#define SCP_TEST_ON()		SHORT_TEST_SetHigh()		//开输出短路测试开关
#define SCP_TEST_OFF()		SHORT_TEST_SetLow()			//关输出短路测试开关
#define BAT_LOSS_D_ON()		BAT_LOSS_SetHigh()			//开电池丢失测试开关
#define BAT_LOSS_D_OFF()	BAT_LOSS_SetLow()			//关电池丢失测试开关
#define BAT_LOSS_IO_STATE()	(BAT_LOSS_GetValue()>>7)	//读取电池丢失测试开关状态
#define SCP_IO_STATE()		(OCP_GetValue()>>5)			//读取OCP引脚电平状态
#if CHECK_HOST_485_EN > 0
#define HOST_485_TX_EN()	DIR_485_SetHigh()			//485发送
#define HOST_485_RX_EN()	DIR_485_SetLow()			//485接收
#else

#endif

#define CLEAR_WDT()			do { wdt_reset(); } while(0)		//喂狗
#define DELAY_MS(n)			_delay_ms(n)			//ms级延时
#define DELAY_US(n)			_delay_us(n)			//us级延时

#define TimerBase_Set(n)  				TCA0.SINGLE.CNT = n;				//设置时基定时器计数值，立即生效	
#define TimerBase_Enable()  			TCA0_Start()						//使能时基定时器
#define CLEAR_TIMERBASE_INTFLAG()      	TCA0_ClearOverflowInterruptFlag()	//清除时基定时器中断标志位
#define TIMERBASE_INTERRUPT_ENABLE()  	TCA0.SINGLE.INTCTRL |= 1 << TCA_SINGLE_OVF_bp; /* Overflow Interrupt: enabled */
#define UART_HOST_INTERRUPT_ENABLE()	USART0_ReceiveInterruptEnable()
#define TIMER_CAP_INTERRUPT_ENABLE()	TCB0_EnableCaptInterrupt()			//使能测试AC电压定时器中断
#define TimerCap_Enable()				TCB0_Start()						//使能测试AC电压定时器
#define TimerCap_Disable()				TCB0_Stop()							//失能测试AC电压定时器


//全局中断开关功能封装
#define INTERRUPT_GLOBAL_ENABLE()		ENABLE_INTERRUPTS()			//全局中断使能
#define INTERRUPT_GLOBAL_DISABLE()		DISABLE_INTERRUPTS()		//全局中断失能


//ADC输入引脚定义
#define	V_CHARGER			((adc_0_channel_t)0x03)					//充电器电压
#define	BAT_M1				((adc_0_channel_t)0x09)					//电池中点电压1
#if CHECK_BAT_3_CELL_EN > 0
#define	BAT_M2				((adc_0_channel_t)0x09)					//电池中点电压2
#define	RT_2				((adc_0_channel_t)0x08)					//电池温度2
#endif
#if CHECK_BAT_RES_EN > 0
#define	BR_T				((adc_0_channel_t)0x0A)					//电池内阻
#endif
#define	RT_1				((adc_0_channel_t)0x08)					//电池温度1
#define	BAT					((adc_0_channel_t)0x09)					//电池总压
#define	AC_SIG				((adc_0_channel_t)0x01)					//AC电压
#define	V_OUT				((adc_0_channel_t)0x07)					//输出电压
#define	VDD					((adc_0_channel_t)0x02)					//VDD电压
#define	I_CHARGER			((adc_0_channel_t)0x04)					//充电电流
#define	I_OUT				((adc_0_channel_t)0x05)					//输出电流
//ADC参数
#define ADC_BITS				(10)				//ADC采样位数
#define ADC_BASE				(1 << ADC_BITS)		//左移，快捷算法
#define ADC_BASE_VOLTAGE		(gf_vmcu)			//ADC基准电压采用标定后的值，默认VDD=5.0V
#define getADC0(pin)    		ADC0_GetConversion(pin)
#define getADC1(pin)    		ADC1_GetConversion(pin)

//DAC参数
#define DACU_BITS				(8)
#define DACU_BASE				(1 << DACU_BITS)
#define DACU_BASE_VOLTAGE		(4.34)
#define DACU_TIMES				(11)
#define setDACU(ad)				DAC0_SetOutput(ad)

//存储介质读写
#define FLASH_READ_BYTE(addr)				EEPROM_Read(addr)
#define FLASH_READ_ARRAY(addr,dat,num)		EEPROM_ReadBlock(addr,dat,num)
#define FLASH_WRITE_BYTE(addr,dat)			EEPROM_Write(addr,dat)
#define FLASH_WRITE_ARRAY(addr,dat,num)		EEPROM_WriteBlock(addr,dat,num) 

//硬件检测放大倍数...
#define ADC_VDD_TIMES			(11.0)				//VDD电压
#define ADC_BAT_TIMES			(11.0)				//电池总压
#define ADC_BAT_MIDDLE_TIMES	(11.0)				//电池中点电压
#define ADC_AC_SIG_TIMES		(96.72)				//AC电压
#define ADC_LOAD_OUTU_TIMES		(11.0)				//输出电压
#define ADC_LOAD_OUTI_TIMES		(13*0.004)			//输出电流，U/(A*R)
#define ADC_CHARGER_V_TIMES		(11.0)				//充电电压
#define ADC_CHARGER_I_TIMES		(1.52)				//充电电流

/****************************************************/  
//系统关键保护值参数宏
#define X_VOLTAGE(n)					((uint16_t)(n))
#define F_VOLTAGE(n)					((float)(n))
#define VOLTAGE(n)						((uint16_t)((n)*100))
#define CURRENT(n)						((uint16_t)((n)*100))
#define	DACU_VOLATAGE(n)				((uint8_t)((n) * 1.0 * DACU_BASE / DACU_BASE_VOLTAGE / DACU_TIMES + 0.5))
#define THRESHOLD_V(n)					((uint16_t)((n)/ADC_LOAD_OUTU_TIMES/ADC_BASE_VOLTAGE*ADC_BASE))
#define THRESHOLD_V_SHORT_25V			(465)								//输出电压约25V ((uint16_t)(25/11/5*1024))
#define THRESHOLD_V_SHORT_1_5V			(28)								//输出电压约1.5V ((uint16_t)(1.5/11/5*1024))
#define THRESHOLD_I_SHORT_80A			(852)								//输出电流约80A ((uint16_t)(80*13*0.004/5*1024))
#define THRESHOLD_V_CHARGER_OFF_80V		(100)								//AC电压约80V ((uint16_t)(100/1024*5/510*117*1000/1.414))

//AC
#define ACPOWER_VOLTAGE_MAINOFF_OVER 	X_VOLTAGE(270)	//关闭AC输入 270
#define ACPOWER_VOLTAGE_SIGNAL_OVER 	X_VOLTAGE(260)	//AC输入过压报警 260
#define ACPOWER_VOLTAGE_OVER_RECOVERY 	X_VOLTAGE(255)	//AC输入恢复 255
#define ACPOWER_VOLTAGE_MAINOFF_LOW 	X_VOLTAGE(90)	//关闭AC输入
#define ACPOWER_VOLTAGE_SIGNAL_LOW 		X_VOLTAGE(95)	//AC输入欠压报警
#define ACPOWER_VOLTAGE_LOW_RECOVERY 	X_VOLTAGE(100)	//AC输入恢复

//输出电压、电流
#define	LOAD_VOLTAGE_OVER_ALARM			VOLTAGE(36.0)	//输出过压报警
#define	LOAD_VOLTAGE_OVER_ALARM_RECOVERY VOLTAGE(34.0)	//输出过压报警恢复
#define	LOAD_VOLTAGE_LOW_ALARM			VOLTAGE(15.0)	//输出欠压报警
#define	LOAD_VOLTAGE_LOW_ALARM_RECOVERY	VOLTAGE(18.0)	//输出欠压报警恢复

#define LOAD_CURRENT_OVER4 				CURRENT(40.0)	//过流4，0.5s关闭输出
#define LOAD_CURRENT_OVER3 				CURRENT(30.0)	//过流3，1s关闭输出
#define LOAD_CURRENT_OVER2 				CURRENT(20.0)	//过流2，2s关闭输出
#define LOAD_CURRENT_OVER1 				CURRENT(9.1)	//过流1，3s关闭输出
#define LOAD_CURRENT_SIGNAL_OVER 		CURRENT(8.4)	//输出过流报警
#define LOAD_CURRENT_SIGNAL_RECOVERY 	CURRENT(7.5)	//输出过流恢复


//BAT
#define BATTERY_VOLTAGE_PORT_SHORT 	    			VOLTAGE(0.17)		//备电端口短路保护
#define BATTERY_VOLTAGE_PORT_SHORT_RECOVERY 	    VOLTAGE(0.25)		//备电端口短路保护恢复
#define BATTERY_VOLTAGE_CHARGEROFF_LOW 				VOLTAGE(15.0)		//备电充电欠压保护
#define BATTERY_VOLTAGE_CHARGEROFF_LOW_RECOVERY 	VOLTAGE(18.5)		//备电充电欠压保护恢复
#define BATTERY_VOLTAGE_CHARGEROFF_OVER 			VOLTAGE(29.5)		//备电充电过压保护
#define BATTERY_VOLTAGE_CHARGEROFF_OVER_RECOVERY 	VOLTAGE(29.0)		//备电充电过压保护恢复
#define BATTERY_VOLTAGE_BATOFF_LOW_LEAD_ACID 		VOLTAGE(21.0)		//备电欠压保护(铅酸电池)
#define BATTERY_VOLTAGE_BATOFF_LOW_LI_ION			VOLTAGE(20.8)		//备电欠压保护(磷酸铁锂电池)
#define BATTERY_VOLTAGE_SIGNAL_LOW 					VOLTAGE(23.0)		//备电欠压报警
#define BATTERY_VOLTAGE_LOW_RECOVERY 				VOLTAGE(24.5)		//备电欠压报警恢复
#define BATTERY_VOLTAGE_SINGLE_OVER					VOLTAGE(15.0)		//电池单节过压报警(铅酸)
#define BATTERY_VOLTAGE_SINGLE_OVER_RECOVERY		VOLTAGE(14.5)		//电池单节过压恢复(铅酸)
#define BATTERY_VOLTAGE_SINGLE_LOW					VOLTAGE(8.0)		//电池单节欠压报警(铅酸)
#define BATTERY_VOLTAGE_SINGLE_LOW_RECOVERY			VOLTAGE(8.5)		//电池单节欠压恢复(铅酸)
#define BATTERY_VOLTAGE_DIFFERENCE_OVER				VOLTAGE(1.5)		//电池间压差报警(铅酸)
#define BATTERY_VOLTAGE_DIFFERENCE_OVER_RECOVERY	VOLTAGE(1.0)		//电池间压差恢复(铅酸)
#define LIION_BAT_VOLTAGE_SINGLE_OVER				VOLTAGE(3.60*10)	//电池单节过压报警(磷酸铁锂电池)
#define LIION_BAT_VOLTAGE_SINGLE_OVER_RECOVERY		VOLTAGE(3.55*10)	//电池单节过压恢复(磷酸铁锂电池)
#define LIION_BAT_VOLTAGE_SINGLE_LOW				VOLTAGE(2.50*10)	//电池单节欠压报警(磷酸铁锂电池)
#define LIION_BAT_VOLTAGE_SINGLE_LOW_RECOVERY		VOLTAGE(2.55*10)	//电池单节欠压恢复(磷酸铁锂电池)
#define LIION_BAT_VOLTAGE_SINGLE_DIFFERENCE_OVER	VOLTAGE(0.5*10)		//电池间压差报警(磷酸铁锂电池)
#define BATTERY_LOST_CHECK_CURRENT					CURRENT(0.15)		//150mA，备电丢失
#define BATTERY_LOST_CHECK_VOLTAGE					VOLTAGE(15)			//15v，备电存在
#define BATTERY_FULL_CHECK_VOLTAGE					VOLTAGE(26.0)		//26.0v，备电充饱判定条件
#define BATTERY_CHARGING_FULL_CURRENT_LEAD_ACID 	CURRENT(0.26)		//0.26A，铅酸电池充饱
#define BATTERY_CHARGING_RECOVERY_CURRENT_LEAD_ACID CURRENT(0.55)		//0.55A，铅酸电池充电中，不考虑假负载等情况
#define BATTERY_CHARGING_FULL_CURRENT_LI_ION		CURRENT(0.65)		//0.65A，磷酸铁锂电池充饱
#define BATTERY_CHARGING_RECOVERY_CURRENT_LI_ION	CURRENT(1.0)		//1A，磷酸铁锂电池充电中，不考虑假负载等情况
#define BATTERY_RESISTANCE_OVER						X_VOLTAGE(100)		//1R
#define BATTERY_RESISTANCE_OVER_RECOVERY			X_VOLTAGE(80)		//0.8R

//Charger
#define CHARGER_VOLTAGE_CHARGEROFF_OVER 			VOLTAGE(29.5)		//充电器异常过压报警
#define CHARGER_VOLTAGE_CHARGEROFF_OVER_RECOVERY 	VOLTAGE(29.0)		//充电器过压保护恢复，因硬件原理不同，暂不考虑此情况
#define CHARGER_VOLTAGE_CHARGEROFF_LOW 				VOLTAGE(15.0)		//充电器异常低压报警
#define CHARGER_VOLTAGE_CHARGEROFF_LOW_RECOVERY 	VOLTAGE(18.0)		//充电器欠压保护恢复，因硬件原理不同，暂不考虑此情况

//VDD 
#define	VDD_VOLTAGE_OVER				VOLTAGE(34.0)	//充电器输出过压报警
#define	VDD_VOLTAGE_OVER_RECOVERY		VOLTAGE(32.0)	//充电器输出过压恢复
#define	VDD_VOLTAGE_LOW					VOLTAGE(15.0)	//充电器输出欠压报警
#define	VDD_VOLTAGE_LOW_RECOVERY		VOLTAGE(17.0)	//充电器输出欠压恢复

#define	VDD_BAT_DIFF_VOLTAGE_OVER		VOLTAGE(2.0)	//充电器输出和电池电压差值过大
#define	VDD_BAT_DIFF_VOLTAGE_RECOVERY	VOLTAGE(1.5)	//充电器输出和电池电压差值过大恢复阈值


/****************************************************/  
//常用判断标志定义
enum 
{
	NO = 0,
	YES,
};	

enum 
{
	CLEAR = 0,
	SET,
};

enum 
{
	CLOSE = 0,
	OPEN,
};	

enum 
{
	LOW = 0,
	HIGH,
	NORMAL,
};
	
enum 
{
	MAIN_OUT = 0,
	BAT_OUT,
};

enum 
{
	LEAD_ACID = 0,
	LI_ION,
};

enum 
{
	UP = 1,
	DOWN,
};

/****************************************************/  
//常用标志位掩码定义
#define	STATE  					(0x01)		//bit0-表示状态，置1表示报警
#define	ACTION_MAINOFF			(0x02)		//bit1-主电状态，置1关，清0开
#define	ACTION_BATOFF			(0x04)		//bit2-备电状态，置1关，清0开
#define	ACTION_CHARGEROFF		(0x08)		//bit3-充电器状态，置1关，清0开
/****************************************************/  

//各数据结构体定义
struct _com_type {
	//uint8_t flags;						//异常关闭标志
	uint8_t COM_FLAG_EMERGENCY;				//应急指令	
};
typedef struct _com_type com_type_t;
extern com_type_t gst_com_type;
	
struct _acpower_type {
	uint8_t ACPOWER_FLAG_VOLTAGE_OVER; 		//AC过压系列标志位，bit0:报警，bit1:保护
	uint8_t ACPOWER_FLAG_VOLTAGE_LOW;  		//AC欠压系列标志位，bit0:报警，bit1:保护
	uint8_t ACPOWER_FLAG_VOLTAGE_LOW_FAST;  //AC欠压快速保护标志位，用于快速关闭充电器
	uint16_t voltage;						//AC电压
	uint16_t ad_value;						//AC电压ad值
};
typedef struct _acpower_type acpower_t;
extern acpower_t gst_acpower;


struct _load_type {
	uint8_t count;								//计数过流次数
	uint8_t LOAD_FLAG_CURRENT_SHORT;			//负载短路
	uint8_t LOAD_FLAG_CURRENT_OVER;				//负载过流 > 9.1A
	uint8_t LOAD_FLAG_CURRENT_SIGNAL_OVER;		//负载过流 8.4A < I < 9.1A
	uint8_t POWER_FLAG_OUTPUT_STATE;
	uint16_t voltage;							//输出电压
	uint16_t current;							//输出电流
};
typedef struct _load_type load_t;
extern load_t gst_load;

	
struct _battery_type {
	uint8_t BATTERY_FLAG_VOLTAGE_LOW; 			//电池欠压 <20.9V    		//bit0-报警   bit2-放电保护	bit3-充电保护
	uint8_t BATTERY_FLAG_VOLTAGE_OVER;			//电池过压 >29.5V			//bit0-报警   			  bit3-充电保护
	uint8_t BATTERY_FLAG_BAT_OVER_TEMP;			//电池过温					//bit0-报警   			  bit3-充电保护
	uint8_t BATTERY_FLAG_PORT_SHORT;			//电池端短路					//bit0-报警 				  bit3-充电保护
#if CHECK_BAT_RES_EN > 0
	uint8_t BATTERY_FLAG_RES_OVER;				//电池内阻过大			
#endif
	uint8_t BATTERY_FLAG_SINGLE_VOLTAGE;		//电池单节电压异常 				//bit0-报警 
	uint8_t BATTERY_FLAG_DIFFERENCE_VOLTAGE;	//电池节间压差异常  			//bit0-报警
	uint8_t BATTERY_FLAG_LOST;					//电池丢失					//bit0-报警
	uint8_t BATTERY_FLAG_FULL;					//电池充满					//bit0-指示
	uint8_t BATTERY_FLAG_SIGNAL_VOLTAGE;		//电池电压过低信号				//bit0-报警
	uint16_t capacity;							//电池电量
	uint16_t voltage;							//电池电压 
	uint16_t m1_voltage;						//电池中点电压1
#if CHECK_BAT_3_CELL_EN > 0
	uint16_t m2_voltage;						//电池中点电压2
#endif
#if CHECK_BAT_RES_EN > 0
	uint16_t resistance;						//电池内阻		
#endif	
	uint16_t chg_current;						//充电电流
	int16_t temp1;								//电池1温度
#if CHECK_BAT_3_CELL_EN > 0
	int16_t temp2;								//电池2温度
#endif
#if CHECK_CHARGER_DAC_EN > 0
	int16_t temp_adjust;	
#endif
};
typedef struct _battery_type battery_t;
extern battery_t gst_battery;


struct _charger_type {
	uint8_t CHARGER_VOLTAGE_ERROR;				//bit0-CHARGER_VOLTAGE_LOW		bit1-CHARGER_VOLTAGE_OVER	bit3-保护
	uint8_t CHARGER_FLAG_STATUS;				//充电状态  	0-充电中   	1-停止充电
	uint8_t VDD_FLAG_VOLTAGE_LOW;				//欠压 <24.0V
	uint8_t VDD_FLAG_VOLTAGE_OVER;				//过压 >34.0V
	uint16_t voltage;							//充电器输出电压
	uint16_t vdd_voltage;						//充电器vdd端输出电压
	uint16_t dac_volatge;						//补偿后的充电电压
};
typedef struct _charger_type charger_t;
extern charger_t gst_charger;




//Global Variable 
extern float 		gf_vmcu;
extern uint8_t 		gu8_tiger_flag;
extern uint8_t  	gu8_detect_count;
extern uint16_t 	gu16_detect_done;
extern uint8_t  	gu8_output_power_flag;		
extern uint8_t		gu8_bat_type_flag;			
extern uint8_t 		gu8_soft_wdg_clear_flag;
extern uint8_t 		gu8_detect_bat_lost_flag;
extern uint8_t  	gu8_get_real_vbat_flag;					//获取电池端口有效电压标志位，目前在应用检测到端口过压时
extern int8_t 		gs8_calib_ac_value;
extern uint8_t  	gu8_detect_battery_resistance_flag;		//检测电池内阻标志位
extern uint8_t 		gu8_check_battery_resistance_time;
extern uint16_t 	gu16_check_battery_resistance_ms;
extern uint16_t 	gu16_battery_res_timer;					//用于内阻检测的长时间定时计数器

#define ac_detect_count 64
extern uint16_t		gu16_ac_ad_value[ac_detect_count];
extern uint8_t      gu8_ac_detect_done;

/****************************************************/ 
//函数声明
//硬件模块初始化，和MCU高度相关
void SYS_Init(void);


/****************************************************/  
//初始化功能函数，初始化硬件以及各种变量，检测硬件是否异常		
/******************/
//参数: void;
//返回: -1：硬件初始化失败
//		0：硬件初始化正常
/******************/
uint8_t Hardware_Init(void);

/******************/
//开机软起动功能函数
//参数: void;
//返回: void;
/******************/
void Soft_Start(void);

//温度补偿
void set_dacu_volatage_of_temperature(float temp);


//等待的方式发送
void Uart_Host_Loop_Write(const uint8_t *p_buffer, uint8_t u8_len);
//中断的方式发送
void Uart_Host_Write(const uint8_t *p_buffer, uint8_t u8_len);

//通讯中断函数中调用
void UART_HOST_TxIsrCb(void);
void UART_HOST_RxIsrCb(void);

//短路保护中断函数中调用
void SCP_HandleIsrCb(void);

/**
 * @brief handler_deal_recv_data
 *          在接收中断对收到的数据验证CRC
 * @param r_data 待处理数据
 * @return void
 info 适用于没有串口空闲中断的MCU模块，在需要及时处理数据时使用
 */
void handler_deal_recv_data(uint8_t dat);

#endif	/* HARDWARE_H */




